package licode.unisop.client.controller;

import licode.unisop.client.api.auth.SopUserAuth;
import licode.unisop.client.info.SopAuthIn;
import licode.unisop.client.info.SopAuthDirectIn;
import licode.unisop.client.utils.*;
import licode.unisop.client.visit.UserAuthVisit;
import licode.unisop.client.vo.SopAuthResult;
import licode.unisop.client.vo.SopAuthUser;
import licode.unisop.client.vo.SopCredential;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @author licode
 */
@RestController
@RequestMapping("/uni-api/v1/auth")
public class SopAuthController extends SopBaseController {
    @Resource
    private HttpServletRequest request;

    @Resource
    private SopUserAuth sopUserAuth;

    @Resource
    private UserAuthVisit userAuthVisit;

    @Resource
    private SopUserAuthUtil sopUserAuthUtil;

    @PostMapping("/captcha/code")
    public SopResult<Map<String, Object>> getCaptchaCode() {
        return MethodCallUtil.exec(null, () -> sopUserAuth.getCaptchaCode());
    }

    @PostMapping("/authorize")
    public SopResult<SopAuthResult> authorize(@RequestBody SopAuthIn authInfo) {
        return MethodCallUtil.exec(null, () -> {
                    handleAuthAccount(authInfo);
                    return userAuthVisit.authorize(authInfo);
                });
    }

    @PostMapping("/token")
    public SopResult<SopAuthUser> token() {
        return MethodCallUtil.exec(null, () -> sopUserAuthUtil.token());
    }

    @PostMapping("/login")
    public SopResult<SopAuthUser> login(@RequestBody SopAuthIn authInfo) {
        return MethodCallUtil.exec(null,
                () -> {
                    handleAuthAccount(authInfo);
                    return userAuthVisit.login(authInfo);
                });
    }

    @PostMapping("/login-direct")
    public SopResult<SopAuthUser> loginDirect(@RequestBody SopAuthDirectIn authInfo) {
        return MethodCallUtil.exec(null,
                () -> userAuthVisit.loginDirect(authInfo));
    }

    @PostMapping("/refresh")
    public SopResult<SopCredential> refresh() {
        return MethodCallUtil.exec(null, () -> sopUserAuthUtil.refresh());
    }

    @PostMapping("/logout")
    public SopResult<Boolean> logout() {
        return MethodCallUtil.exec(null,
                () -> {
                    sopUserAuthUtil.logout();
                    return true;
                });
    }

    @PostMapping("/session/logout")
    public SopResult<Boolean> logoutSession() {
        return MethodCallUtil.exec(null,
                () -> {
                    sopUserAuthUtil.logoutSession();
                    return true;
                });
    }

    private void handleAuthAccount(SopAuthIn authInfo) {
        if (StringUtil.isBlank(authInfo.getAccount())) {
            authInfo.setAccount(SopRequestParse.getValue(request, SopAuthConst.USERNAME));
        }
        if (StringUtil.isBlank(authInfo.getCategory())) {
            authInfo.setCategory(SopRequestParse.getValue(request, SopAuthConst.CATEGORY));
        }
        if (StringUtil.isBlank(authInfo.getAuthCode())) {
            authInfo.setAuthCode(SopRequestParse.getValue(request, SopAuthConst.PASSWORD));
        }
        if (StringUtil.isBlank(authInfo.getAuthType())) {
            authInfo.setAuthType(SopRequestParse.getValue(request, SopAuthConst.GRANT_TYPE));
        }
    }
}
